package org.lee.fc;

import org.lee.fc.json.Boxscore;
import org.lee.fc.json.Result;
import org.lee.fc.util.JsonUtil;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.time.LocalDate;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.concurrent.CompletableFuture;

/**
 * GamePageParser
 *
 * @author dralee
 * @date 2022-01-25 18:29:39
 **/
public class GamePageParser {
    private void saveResultList(List<Result> result) {
        result.parallelStream().forEach(this::saveResultToFile);
    }

    private void saveResultToFile(Result result) {
        Boxscore boxscore = result.getData().getBoxscore();
        final String awayFname = boxscore.getAwayFname();
        final String homeFname = boxscore.getHomeFname();
        final String date = boxscore.getDate();
        String fileName = String.format("%s_%s_at_%s.txt", date, awayFname, homeFname);
        fileName = fileName.replaceAll("\\s+", "_").replace(",", "");
        File dir = new File("build/data");
        dir.mkdir();
        try {
            File file = new File(dir + File.separator + fileName);
            Files.write(file.toPath().toAbsolutePath(), JsonUtil.toJsonPretty(result).getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private int getTotalScore(Result result) {
        Boxscore boxscore = result.getData().getBoxscore();
        final String awayTeamRuns = boxscore.getLinescore().getAwayTeamRuns();
        final String homeTeamRuns = boxscore.getLinescore().getHomeTeamRuns();
        return Integer.parseInt(awayTeamRuns) + Integer.parseInt(homeTeamRuns);
    }

    public OptionalInt getMaxScore(List<Result> results) {
        return results.stream().mapToInt(this::getTotalScore).max();
    }

    public Optional<Result> getMaxGame(List<Result> results) {
        return results.stream().max(Comparator.comparingInt(this::getTotalScore));
    }

    public void printGames(LocalDate startDate, int days) {
        final CompletableFuture<List<Result>> future = CompletableFuture.supplyAsync(new GamePageLinksSupplier(startDate, days)).thenApply(new BoxScoreRetriever());
        final CompletableFuture<Void> futureWrite = future.thenAcceptAsync(this::saveResultList).exceptionally(e -> {
            System.out.println(e.getMessage());
            return null;
        });
        final CompletableFuture<OptionalInt> futureMaxScore = future.thenApplyAsync(this::getMaxScore);
        final CompletableFuture<Optional<Result>> futureMaxGame = future.thenApplyAsync(this::getMaxGame);
        final CompletableFuture<String> futureMax = futureMaxScore.thenCombineAsync(futureMaxGame, (score, result) -> String.format("Hightest score: %d, Max Game: %s", score.orElse(0), result.orElse(null)));
        CompletableFuture.allOf(futureWrite, futureMax).join();
        future.join().forEach(System.out::println);
        System.out.println(futureMax.join());

    }
}
